package idv.cjcat.pyronova.render {
	import flash.display.BitmapData;
	import flash.display.IBitmapDrawable;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import idv.cjcat.pyronova.pyro;
	
	public final class Graphics {
		
		private var _rect:Rectangle;
		private var _point:Point;
		
		public function Graphics(bottomBuffer:BitmapData) {
			_buffers = Vector.<BitmapData>([bottomBuffer]);
			_rect = bottomBuffer.rect;
			_point = new Point();
		}
		
		//bitmap
		//------------------------------------------------------------------------------------------------
		
		public final function rect():Rectangle { return bottomBuffer().rect; }
		
		public final function colorTransform(transform:ColorTransform):void {
			_buffers[_topBufferIndex].colorTransform(_rect, transform);
		}
		
		public final function draw(source:IBitmapDrawable, matrix:Matrix = null, colorTransform:ColorTransform = null, blendMode:String = null, smoothing:Boolean = false):void {
			_buffers[_topBufferIndex].draw(source, matrix, colorTransform, blendMode, null, smoothing);
		}
		
		public final function fillRect(rect:Rectangle = null, color:uint = 0x00000000):void {
			if (!rect) rect = _rect;
			_buffers[_topBufferIndex].fillRect(rect, color);
		}
		
		private var _dest:Point = new Point();
		public final function copyPixels(source:BitmapData, sourceRect:Rectangle, destX:int, destY:int, mergeAlpha:Boolean):void {
			if (sourceRect == null) sourceRect = source.rect;
			
			_dest.x = destX;
			_dest.y = destY;
			_buffers[_topBufferIndex].copyPixels(source, sourceRect, _dest, null, null, mergeAlpha);
		}
		
		//------------------------------------------------------------------------------------------------
		//end of bitmap
		
		
		//buffer
		//------------------------------------------------------------------------------------------------
		
		private var _buffers:Vector.<BitmapData>;
		private var _topBufferIndex:int = 0;
		
		public final function pushBuffer():void {
			//expand buffer vector if full
			if (++_topBufferIndex == _buffers.length) {
				++_buffers.length;
				_buffers[_topBufferIndex] = new BitmapData(_rect.width, _rect.height, true, 0x00000000);
			}
			_buffers[_topBufferIndex].fillRect(_rect, 0x00000000);
		}
		
		public final function collapseBuffer():void {
			_buffers[_topBufferIndex - 1].copyPixels(_buffers[_topBufferIndex], _rect, _point, null, null, true);
			--_topBufferIndex;
		}
		
		public final function blendBuffer(blendMode:String = null):void {
			_buffers[_topBufferIndex - 1].draw(_buffers[_topBufferIndex], null, null, blendMode);
			--_topBufferIndex;
		}
		
		public final function topBuffer():BitmapData {
			return _buffers[_topBufferIndex];
		}
		
		public final function bottomBuffer():BitmapData {
			return _buffers[0];
		}
		
		public final function lockBuffers():void {
			for (var i:int = 0; i <= _topBufferIndex; ++i) {
				_buffers[i].lock();
			}
		}
		
		public final function unlockBuffers():void {
			for (var i:int = 0; i <= _topBufferIndex; ++i) {
				_buffers[i].unlock();
			}
		}
		
		//------------------------------------------------------------------------------------------------
		//end of buffer
	}
}